#include "StdAfx.h"
#include "RegionView.h"
#include "imageview_p.h"
#include "regionitem.h"
#include "RegionScene.h"
#include "command.h"

class RegionViewPrivate : public ImageViewPrivate
{
public:
	RegionViewPrivate(RegionView* parent)
		: ImageViewPrivate(parent)
		, prototypeRegion(0)
		, flag(false)
	{

	}

private:
	Q_DECLARE_PUBLIC(RegionView);
	Region* prototypeRegion;
	QPoint origin;
	QPoint current;
	QPolygon polygon;
	bool flag;
};

RegionView::RegionView(QWidget *parent)
	: ImageView(*new RegionViewPrivate(this), parent)
{
	Q_D(RegionView);
	setDragMode(QGraphicsView::RubberBandDrag);
}

RegionView::~RegionView()
{

}

Region* RegionView::prototyperegionItem() const
{
	return d_func()->prototypeRegion;
}

void RegionView::setPrototypeRegion(Region* prototypeRegion)
{
	Q_D(RegionView);
	d->prototypeRegion = prototypeRegion;
}


RegionScene* 
RegionView::regionScene() const
{
	return qobject_cast<RegionScene*>(QGraphicsView::scene());
}

void 
RegionView::setregionItemscene(RegionScene* scene)
{
	Q_ASSERT(scene);
	QGraphicsView::setScene(scene);
}

void RegionView::mousePressEvent(QMouseEvent *event)
{
	Q_D(RegionView);
	if(event->button() == Qt::LeftButton)
	{
		d->flag = true;
		if(prototyperegionItem())
		{
			d->origin = event->pos();
			if(prototyperegionItem()->type() == PolygonType)
			{
				d->polygon << event->pos();
				viewport()->update();
			}
			event->accept();
			return;
		}
	}
	ImageView::mousePressEvent(event);	
	
}


void RegionView::mouseMoveEvent(QMouseEvent *event)
{
	Q_D(RegionView);
	ImageView::mouseMoveEvent(event);	
	if(prototyperegionItem())
	{
		d->current = event->pos();		
		viewport()->update();
	}
	
	
}

void RegionView::mouseReleaseEvent(QMouseEvent *event)
{
	Q_D(RegionView);
	ImageView::mouseReleaseEvent(event);
	if(prototyperegionItem())
	{
		if ((event->button() == Qt::LeftButton && prototyperegionItem()->type() != PolygonType) ||
			(event->button() == Qt::RightButton && prototyperegionItem()->type() == PolygonType))
		{
			d->flag = false;	
			viewport()->update();
			switch(prototyperegionItem()->type())
			{
			case RectangleType:
			case EllipseType:			
			case RectangleRingType:
			case EllipseRingType:
				{
					QPointF origin = mapToScene(d->origin);
					QPointF current = mapToScene(event->pos());
					QRectF rect(origin,current);
					QRectF selectedRect = rect.normalized();
					if(selectedRect.isValid())
					{
						Region* item = prototyperegionItem()->clone();
						item->setRectangleSize(rect.size());
						item->setPos(rect.center());
						regionScene()->undoStack()->push(new AddCommand(regionScene(),item));
					}
				}
				break;
			case PolygonType:
				{
					if(d->polygon.count() >= 3)
					{
						QPolygonF points = mapToScene(d->polygon);
						Region* item = prototyperegionItem()->clone();
						PolygonItem* polygon = qgraphicsitem_cast<PolygonItem*>(item);
						Q_ASSERT(polygon);
						polygon->setPolygon(points);
						regionScene()->undoStack()->push(new AddCommand(regionScene(),item));
					}
					d->polygon.clear();
				}
				break;
			default:
				break;
			}
		}
	}
}

void RegionView::paintEvent(QPaintEvent* event)
{
	Q_D(RegionView);
	ImageView::paintEvent(event);	
	if (prototyperegionItem() && d->flag)
	{
		QPainter painter(viewport());
		painter.save();
		painter.setRenderHint(QPainter::Antialiasing);
		QPainterPath path;
		int type = prototyperegionItem()->type();
		switch(type)
		{
		case RectangleType:
		case RectangleRingType:
			{
				QRect rect(d->origin, d->current);
				path.addRect(rect);				
			}
			break;
		case EllipseType:
		case EllipseRingType:
			{
				QRect rect(d->origin, d->current);
				path.addEllipse(rect);				
			}
			break;
		case PolygonType:
			{
				path.addPolygon(d->polygon);				
			}
			break;
		default:
			Q_ASSERT(false);
			break;
		}
		QPen dotPen(Qt::darkMagenta,1.5,Qt::DotLine);
		painter.setPen(dotPen);
		painter.drawPath(path);
		painter.restore();		
	}		
}